﻿using AMS.Services.DomainModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.EntityFrameworkCore;
using OA.Infrastructure.Models;
using System.Linq.Expressions;

namespace AMS.WebApi.Controllers;

[ApiController]
[Authorize(Policy = "ams")]
[Route("api/[controller]")]
public class TelemetryController : ControllerBase
{
    private readonly DbContext _context;

    public TelemetryController(DbContext context)
    {
        _context = context;
    }

    [HttpGet]
    public async Task<OperationalResult<TelemetryModel>> GetDataAsync()
    {
        var result = new OperationalResult<TelemetryModel>();

        var currentUser = await _context.CurrentUserAsync(HttpContext.RequestAborted);

        var lastVisitedDate = currentUser.LastVisitedDate;

        currentUser.LastVisitedDate = DateTime.UtcNow;
        _context.Set<User>().Update(currentUser);

        await _context.SaveChangesAsync(HttpContext.RequestAborted);

        var accessExpression = currentUser.Account == "admin"
            ? (n => true)
            : (Expression<Func<Approval, bool>>?)(
                n => n.Committer.Id == currentUser.Id ||
                n.ApprovalDetails.Where(n => n.Approver.Id == currentUser.Id).Any());

        var approvalCount = await _context.Set<Approval>()
            .Include(x => x.Committer)
            .Include(x => x.ApprovalDetails).ThenInclude(x => x.Approver)
            .Where(accessExpression)
            .CountAsync(x => x.Status == Services.Enums.ApprovalStatus.Pending, HttpContext.RequestAborted);

        var newApprovalCount = await _context.Set<Approval>()
            .Include(x => x.Committer)
            .Include(x => x.ApprovalDetails).ThenInclude(x => x.Approver)
            .Where(accessExpression)
            .CountAsync(x => x.Status == Services.Enums.ApprovalStatus.Pending && x.CreatedDate > lastVisitedDate, HttpContext.RequestAborted);

        var fixedAssetsCount = await _context.Set<FixedAssetsRepo>()
            .CountAsync(x => x.Status == Services.Enums.AssetsStatus.Normal, HttpContext.RequestAborted);
        var newFixedAssetsCount = await _context.Set<FixedAssetsRepo>()
            .CountAsync(x => x.Status == Services.Enums.AssetsStatus.Normal && x.CreatedDate > lastVisitedDate, HttpContext.RequestAborted);

        var freeAssetsCount = await _context.Set<FreeAssetsRepo>()
            .CountAsync(x => x.Status == Services.Enums.AssetsStatus.Normal, HttpContext.RequestAborted);
        var newFreeAssetsCount = await _context.Set<FreeAssetsRepo>()
            .CountAsync(x => x.Status == Services.Enums.AssetsStatus.Normal && x.CreatedDate > lastVisitedDate, HttpContext.RequestAborted);

        var userCount = await _context.Set<User>()
            .CountAsync(x => !x.IsDeleted, HttpContext.RequestAborted);
        var newUserCount = await _context.Set<User>()
            .CountAsync(x => !x.IsDeleted && x.CreatedDate > lastVisitedDate, HttpContext.RequestAborted);

        result.Data = new TelemetryModel
        {
            ApprovalCount = approvalCount,
            NewApprovalCount = newApprovalCount,
            FixedAssetsCount = fixedAssetsCount,
            NewFixedAssetsCount = newFixedAssetsCount,
            FreeAssetsCount = freeAssetsCount,
            NewFreeAssetsCount = newFreeAssetsCount,
            UserCount = userCount,
            NewUserCount = newUserCount
        };

        return result;
    }
}